/*
 * Copyright 2017 JessYan
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package me.jessyan.art.utils;


import ohos.aafwk.ability.Ability;

import ohos.aafwk.content.Intent;
import ohos.agp.components.*;

import ohos.net.NetCapabilities;
import ohos.rpc.RemoteException;
import ohos.system.version.SystemVersion;

import java.text.NumberFormat;

import ohos.app.Context;
import ohos.data.usage.DataUsage;

import java.util.Optional;

import ohos.net.NetManager;

import ohos.agp.window.service.WindowManager;
import ohos.bundle.BundleInfo;
import ohos.agp.components.Component;
import ohos.bundle.ElementName;

import ohos.hiviewdfx.HiLog;

import java.util.Locale;

import ohos.telephony.NetworkState;
import ohos.telephony.RadioInfoManager;
import ohos.utils.net.Uri;

import ohos.agp.components.AttrSet;

/**
 * ================================================
 * 获取设备常用信息和处理设备常用操作的工具类
 * <p>
 * Created by JessYan on 2016/3/15
 * <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
 * <a href="https://github.com/JessYanCoding">Follow me</a>
 * ================================================
 */

public final class DeviceUtils {
    // 手机网络类型
    public static final int NETTYPE_WIFI = 0x01;
    public static final int NETTYPE_CMWAP = 0x02;
    public static final int NETTYPE_CMNET = 0x03;

    public static boolean GTE_HC;
    public static boolean GTE_ICS;
    public static boolean PRE_HC;
    private static Boolean _hasBigScreen = null;
    private static Boolean _hasCamera = null;
    private static Boolean _isTablet = null;
    private static Integer _loadFactor = null;
    public static float displayDensity = 0.0F;
    private static Throwable throwable;
    private static Locale locale;
    private static Object Environment;
    private static AttrSet attrSet;
    private static Object Build;
    private static DataUsage dataUsage;
    private static Object Context;
    private static Object Intent;
    private static final float NUM_16 = 160F;
    private static final float NUM_15 = 1.5F;
    private static final int NUM_0 = 0xf;
    private static final int NUM_3 = 3;
    private static final int NUM_26 = 268435456;
    private static final int NUM_2 = 0x34c40000;
    private static final int NUM_14 = 14;
    private static final int NUM_11 = 11;


    static {
        GTE_ICS = SystemVersion.getApiVersion() >= NUM_14;
        GTE_HC = SystemVersion.getApiVersion() >= NUM_11;
        PRE_HC = SystemVersion.getApiVersion() < NUM_11;
    }

    private DeviceUtils() {
        throw new IllegalStateException("you can't instantiate me!");
    }

    /**
     * dp转px
     *
     * @param context
     * @param dp
     * @return
     */
    public static float dpToPixel(Context context, float dp) {

        return dp * (getDisplayMetrics(context).densityDpi / NUM_16);
    }

    /**
     * px转dp
     *
     * @param context
     * @param f
     * @return
     */
    public static float pixelsToDp(Context context, float f) {

        return f / (getDisplayMetrics(context).densityDpi / NUM_16);
    }

    public static int getDefaultLoadFactor(Context context) {
        if (_loadFactor == null) {
            Integer integer = Integer.valueOf(NUM_0 & context
                    .getResourceManager().getConfiguration().direction);
            _loadFactor = integer;
            _loadFactor = Integer.valueOf(Math.max(integer.intValue(), 1));
        }
        return _loadFactor.intValue();
    }

    public static float getDensity(Context context) {
        if (displayDensity == 0.0)
            displayDensity = getDisplayMetrics(context).density;
        return displayDensity;
    }

    public static DisplayMetrics getDisplayMetrics(Context context) {
        DisplayMetrics displaymetrics = new DisplayMetrics();

        return displaymetrics;
    }

    /**
     * 屏幕高度
     *
     * @param context
     * @return
     */
    public static float getScreenHeight(Context context) {
        return getDisplayMetrics(context).heightPixels;
    }

    /**
     * 屏幕宽度
     *
     * @param context
     * @return
     */
    public static float getScreenWidth(Context context) {
        return getDisplayMetrics(context).widthPixels;
    }

    public static boolean hasBigScreen(Context context) {
        boolean flag = true;
        if (_hasBigScreen == null) {

            boolean flag1;
            if ((NUM_0 & context.getResourceManager()
                    .getConfiguration().direction) >= NUM_3)
                flag1 = flag;
            else
                flag1 = false;
            Boolean boolean1 = Boolean.valueOf(flag1);
            _hasBigScreen = boolean1;
            if (!boolean1.booleanValue()) {
                if (getDensity(context) <= NUM_15)
                    flag = false;
                _hasBigScreen = Boolean.valueOf(flag);
            }
        }
        return _hasBigScreen.booleanValue();
    }

    /**
     * 设备是否有实体菜单
     *
     * @param context
     * @return
     */
    //todo ViewConfiguration 未提供
//    public static boolean hasHardwareMenuKey(Context context) {
//        boolean flag = false;
//        if (PRE_HC)
//            flag = true;
//        else if (GTE_ICS) {
//            flag = ViewConfiguration.get(context).hasPermanentMenuKey();
//        } else
//            flag = false;
//        return flag;
//    }

    /**
     * 网络是否连接
     *
     * @param context 上下文
     * @return true表示网络已经连接，并且可以上网。false表示网络没连接，或者网络连接了，但是不能上网
     */
    public static boolean hasInternet(Context context) {
        NetManager netManager = NetManager.getInstance(context);
        NetCapabilities netCapabilities = netManager.getNetCapabilities(netManager.getDefaultNet());
        // NetCapabilities.NET_CAPABILITY_VALIDATED表示连接了网络，并且可以上网
        return netCapabilities.hasCap(NetCapabilities.NET_CAPABILITY_VALIDATED);
    }


    /**
     * 当前的包是否存在
     *
     * @param context
     * @param pckName
     * @return
     */
    public static boolean isPackageExist(Context context, String pckName) {
        try {
            BundleInfo pckInfo = context.getBundleManager().getBundleInfo(pckName, 0);
            if (pckInfo != null)
                return true;

        } catch (RemoteException e) {
            HiLog.debug(null, throwable.getMessage());
        }
        return false;
    }

    public static void hideAnimatedView(Component view) {
        if (PRE_HC && view != null)
            view.setPadding(view.getWidth(), 0, 0, 0);
    }

    /**
     * 是否是横屏
     *
     * @param context
     * @return
     */
    public static boolean isLandscape(Context context) {
        boolean flag;
        if (context.getResourceManager().getConfiguration().direction == 2)
            flag = true;
        else
            flag = false;
        return flag;
    }

    /**
     * 是否是竖屏
     *
     * @param context
     * @return
     */
    public static boolean isPortrait(Context context) {
        boolean flag = true;
        if (context.getResourceManager().getConfiguration().direction != 1)
            flag = false;
        return flag;
    }

    public static boolean isTablet(Context context) {
        if (_isTablet == null) {
            boolean flag;
            if ((NUM_0 & context.getResourceManager()
                    .getConfiguration().direction) >= NUM_3)
                flag = true;
            else
                flag = false;
            _isTablet = Boolean.valueOf(flag);
        }
        return _isTablet.booleanValue();
    }

    public static void showAnimatedView(Component view) {
        if (PRE_HC && view != null)
            view.setPadding(0, 0, 0, 0);
    }

    public static boolean isSdcardReady() {
        return "mounted".equals(DataUsage
                .getDiskMountedStatus());
    }

    public static String getCurCountryLan(Context context) {
        return locale.getLanguage()
                + "-"
                + locale
                .getCountry();
    }

    public static boolean isZhCN(Context context) {
        String lang = locale.getCountry();
        if (lang.equalsIgnoreCase("CN")) {
            return true;
        }
        return false;
    }

    public static String percent(double p1, double p2) {
        String str;
        double p3 = p1 / p2;
        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMinimumFractionDigits(2);
        str = nf.format(p3);
        return str;
    }

    public static String percent2(double p1, double p2) {
        String str;
        double p3 = p1 / p2;
        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMinimumFractionDigits(0);
        str = nf.format(p3);
        return str;
    }

    public static void setFullScreen(Ability activity) {
        Optional<WindowManager.LayoutConfig> params = activity.getWindow().getLayoutConfig();
        //params.flags |= WindowManager.LayoutConfig.MARK_FULL_SCREEN;
        attrSet.getAttr(String.valueOf(params));
        activity.getWindow().clearFlags(
                WindowManager.LayoutConfig.FIRST_SYSTEM_WINDOW);
    }

    public static void cancelFullScreen(Ability activity) {
        Optional<WindowManager.LayoutConfig> params = activity.getWindow().getLayoutConfig();
        //  params.flags &= (~WindowManager.LayoutConfig.MARK_FULL_SCREEN);
        attrSet.getAttr(String.valueOf(params));
        activity.getWindow().clearFlags(
                WindowManager.LayoutConfig.FIRST_SYSTEM_WINDOW);
    }

    public static BundleInfo getPackageInfo(Context context, String pckName) {
        try {
            return context.getBundleManager().getBundleInfo(pckName, 0);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取版本号
     *
     * @param context
     * @return
     */
    public static int getVersionCode(Context context) {
        int versionCode = 0;
        try {
            versionCode = context.getBundleManager().getBundleInfo(context.getBundleName(), 0).getVersionCode();
        } catch (RemoteException e) {
            e.printStackTrace();
        }

        return versionCode;
    }

    /**
     * 获取指定包名应用的版本号
     *
     * @param context
     * @param packageName
     * @return
     */
    public static int getVersionCode(Context context, String packageName) {
        int versionCode = 0;
        try {
            versionCode = context.getBundleManager().getBundleInfo(context.getBundleName(), 0).getVersionCode();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return versionCode;
    }

    /**
     * 获取版本名
     *
     * @param context
     * @return
     */
    public static String getVersionName(Context context) {
        String name = "";
        try {
            name = context.getBundleManager().getBundleInfo(context.getBundleName(),
                    0).name;
        } catch (RemoteException ex) {
            name = "";
        }
        return name;
    }

    /**
     * 拨打电话
     *
     * @param context
     * @param number
     */
    public static void openDial(Context context, String number) {
        Intent it = new Intent(new Intent());
        context.startAbility(it, 0);
    }

    public static void openSMS(Context context, String smsBody, String tel) {
        Intent it = new Intent(new Intent());
        it.setFlags(Integer.parseInt(smsBody));
        context.startAbility(it, 0);
    }

    public static void openDail(Context context) {
        Intent intent = new Intent();
        intent.setFlags(NUM_26);
        context.startAbility(intent, 0);
    }

    public static void openSendMsg(Context context) {
        Intent intent = new Intent(new Intent());
        intent.setFlags(NUM_26);
        context.startAbility(intent, 0);
    }

    public static void openCamera(Context context) {
        Intent intent = new Intent(); // 调用照相机
        intent.setFlags(NUM_2);
        context.startAbility(intent, 0);
    }

    public static String getIMEI(Context context) {
        return RadioInfoManager.getInstance(context).getImei(0);
    }

    public static String getPhoneType() {
        return Build.toString();
    }

    public static void openApp(Context context, String packageName) throws RemoteException {
        Intent mainIntent = context.getBundleManager().getLaunchIntentForBundle(packageName);
        if (mainIntent == null) {
            mainIntent = new Intent();
        } else {
            HiLog.error(null, "mainIntent is exist");
        }
        context.startAbility(mainIntent, 0);
    }


    public static boolean openAppActivity(Context context, String packageName,
                                          String activityName) {
        Intent intent = new Intent(new Intent());
        ElementName cn = new ElementName(null);
        intent.setElement(cn);
        try {
            context.startAbility(intent, 0);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * wifi是否开启
     *
     * @param context
     * @return
     */
    public static NetworkState isWifiOpen(Context context) {
        return RadioInfoManager.getInstance(context).getNetworkState(0);
    }

    /**
     * 卸载软件
     *
     * @param context
     * @param packageName
     */
    public static void uninstallApk(Context context, String packageName) {
        if (isPackageExist(context, packageName)) {
            Intent uninstallIntent = new Intent(new Intent());
            context.startAbility(uninstallIntent, 0);
        }
    }

    public static boolean hasStatusBar(Ability activity) {
        if ((WindowManager.LayoutConfig.FIRST_SYSTEM_WINDOW) == WindowManager.LayoutConfig.FIRST_SYSTEM_WINDOW) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 判断是否存在sd卡
     *
     * @return
     */
    public static boolean isExitsSdcard() {
        if (dataUsage.getClass().equals("mounted"))
            return true;
        else
            return false;
    }
}


